package com.ugoodtech.mdcc.core.service.impl;

import com.mysema.query.BooleanBuilder;
import com.ugoodtech.mdcc.core.Constants;
import com.ugoodtech.mdcc.core.domain.*;
import com.ugoodtech.mdcc.core.dto.JsonResponse;
import com.ugoodtech.mdcc.core.helper.ProvinceBrandPoJo;
import com.ugoodtech.mdcc.core.helper.ProvinceBrandSearchHelper;
import com.ugoodtech.mdcc.core.helper.SearchVoId;
import com.ugoodtech.mdcc.core.model.entity.StationColorReportExample;
import com.ugoodtech.mdcc.core.model.entity.StationColorReportExample.Criteria;
import com.ugoodtech.mdcc.core.model.entity.StationReportExample;
import com.ugoodtech.mdcc.core.model.entity.Stations;
import com.ugoodtech.mdcc.core.model.entity.StationsExample;
import com.ugoodtech.mdcc.core.model.mapper.StationColorReportMapper;
import com.ugoodtech.mdcc.core.model.mapper.StationReportMapper;
import com.ugoodtech.mdcc.core.model.mapper.StationsMapper;
import com.ugoodtech.mdcc.core.repository.StationColorReportRepository;
import com.ugoodtech.mdcc.core.repository.StationReportRepository;
import com.ugoodtech.mdcc.core.service.SearchPermissionsService;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 基于基础报告，通过筛选的省份+品牌查询用户能看到的报告ID
 */
@Service
public class SearchPermissionsServiceImpl implements SearchPermissionsService {

    @Autowired
    private ProvinceBrandSearchHelper provinceBrandSearchHelper;

    @Autowired
    private StationReportRepository stationReportRepository;

    @Autowired
    private StationColorReportRepository stationColorReportRepository;

    @Autowired
    private StationReportMapper stationReportMapper;

    @Autowired
    private StationColorReportMapper stationColorReportMapper;

    @Autowired
    private StationsMapper stationsMapper;

    /**
     * 获取经销商能查询的报告
     *
     * @param userProfile
     * @return
     */
    @Override
    public SearchVoId getDealersStationId(UserProfile userProfile, String province, String brand) {
        if (userProfile != null && userProfile.getDepartmentList().get(0).getStationList() != null) {
            List<Station> stationList = userProfile.getDepartmentList().get(0).getStationList();
            List<Long> stationIds = new ArrayList<>();
            for (Station station : stationList) {
                stationIds.add(station.getId());
            }
            return getDealersColor(stationIds, province, brand);
        } else {
            return new SearchVoId();
        }
    }

    //获取经销商的维修站
    private SearchVoId getDealersColor(List<Long> stationIds, String province, String brand) {
        SearchVoId searchVoId = new SearchVoId();
        QStationReport qStationReport = QStationReport.stationReport;
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qStationReport.deleted.eq(false));
        builder.and(qStationReport.enabled.eq(true));
        builder.and(qStationReport.category.eq(Constants.TECHCOLOR_REPORT));
        builder.and(qStationReport.station.id.in(stationIds));
        if (StringUtils.isNotEmpty(province)) {
            String[] provinceArray = province.split(",");
            builder.and(qStationReport.station.province.in(provinceArray));
        }
        List<StationReport> stationReport = (List<StationReport>) stationReportRepository.findAll(builder);
        Map<Long, Integer> reportMap = new HashMap<>();
        Map<Long, Integer> stationMap = new HashMap<>();
        for (StationReport report : stationReport) {
            reportMap.put(report.getId(), 1);
            stationMap.put(report.getStation().getId(), 1);
        }
        Map<Long, Integer> brandReportMap = new HashMap<>();
        Map<Long, Integer> brandStationMap = new HashMap<>();
        if (StringUtils.isNotEmpty(brand)) {
            qStationReport = QStationReport.stationReport;
            builder = new BooleanBuilder();
            builder.and(qStationReport.deleted.eq(false));
            builder.and(qStationReport.enabled.eq(true));
            builder.and(qStationReport.category.eq(Constants.TECHCOLOR_REPORT));
            builder.and(qStationReport.id.in(reportMap.keySet()));
            String[] brandArray = brand.split(",");
            for (String s : brandArray) {
                builder.and(qStationReport.station.brand.like("%" + s + "%"));
                stationReport = (List<StationReport>) stationReportRepository.findAll(builder);
                for (StationReport report : stationReport) {
                    brandReportMap.put(report.getId(), 1);
                    brandStationMap.put(report.getStation().getId(), 1);
                }
            }
        }
        if (StringUtils.isNotEmpty(brand)) {
            searchVoId.setResultStationReportId(new ArrayList<>(brandReportMap.keySet()));
            searchVoId.setResultStationId(new ArrayList<>(brandStationMap.keySet()));
        } else {
            searchVoId.setResultStationReportId(new ArrayList<>(reportMap.keySet()));
            searchVoId.setResultStationId(new ArrayList<>(stationMap.keySet()));
        }
        return searchVoId;
    }


    /**
     * 通过筛选的省份+品牌查询用户能看到的报告ID
     *
     * @param userProfile 用户详细信息
     * @param province    筛选的省份
     * @param brand       筛选的品牌
     * @return 能看到的报告ID
     */
    @Override
    public SearchVoId searchColorReportByProvinceBrand(UserProfile userProfile, String province, String brand) {
        ProvinceBrandPoJo provinceBrandPoJo =
                provinceBrandSearchHelper.getUserSearchProvinceBrand(userProfile, province, brand, true);
        //筛选条件：省份
        if (StringUtils.isNotEmpty(province) && StringUtils.isEmpty(brand)) {
            List<Long> reportId;
            //当省份权限或者品牌权限一个为空时
            if (provinceBrandPoJo.getOwnProvinceList().isEmpty() || provinceBrandPoJo.getOwnBrandList().isEmpty()) {
                //省份权限为空 品牌权限不为空
                if (provinceBrandPoJo.getOwnProvinceList().isEmpty() && !provinceBrandPoJo.getOwnBrandList().isEmpty()) {
                    List<Long> ownBrandReportId = getReportIdByBrand(provinceBrandPoJo.getOwnBrandList(), null);
                    reportId = getReportIdByProvince(null, provinceBrandPoJo.getSearchProvinceList(), ownBrandReportId);
                    return getFinalResultReportId(reportId);
                }
                //省份权限不为空 品牌权限为空
                if (!provinceBrandPoJo.getOwnProvinceList().isEmpty() && provinceBrandPoJo.getOwnBrandList().isEmpty()) {
                    if (provinceBrandPoJo.getCanProvinceList().isEmpty()) {
                        return new SearchVoId();
                    } else {
                        List<Long> ownProvinceReportId = getReportIdByProvince(provinceBrandPoJo.getCanProvinceList(), null, null);
                        return getFinalResultReportId(ownProvinceReportId);
                    }
                }
            } else {
                //省份权限 品牌权限都不为空时, 如果可以过滤后本次可以查询的省份为空,
                if (provinceBrandPoJo.getCanProvinceList().isEmpty()) {
                    List<Long> ownProvinceReportId = getReportIdByProvince(null, provinceBrandPoJo.getSearchProvinceList(), null);
                    reportId = getReportIdByBrand(provinceBrandPoJo.getOwnBrandList(), ownProvinceReportId);
                    return getFinalResultReportId(reportId);
                }
                // 如果可以过滤后本次可以查询的省份不为空, 先查找可以这些省份的报告
                reportId = getReportIdByProvince(provinceBrandPoJo.getCanProvinceList(), null, null);
//                reportId = getReportIdByBrand(provinceBrandPoJo.getOwnBrandList(), ownProvinceReportId);
                return getFinalResultReportId(reportId);
            }
        }

        //筛选条件：品牌
        if (StringUtils.isEmpty(province) && StringUtils.isNotEmpty(brand)) {
            List<Long> reportId;
            //当省份权限或者品牌权限一个为空时
            if (provinceBrandPoJo.getOwnProvinceList().isEmpty() || provinceBrandPoJo.getOwnBrandList().isEmpty()) {
                //省份权限为空 品牌权限不为空
                if (provinceBrandPoJo.getOwnProvinceList().isEmpty() && !provinceBrandPoJo.getOwnBrandList().isEmpty()) {
                    if (provinceBrandPoJo.getCanBrandList().isEmpty()) {
                        return new SearchVoId();
                    } else {
                        reportId = getReportIdByBrand(provinceBrandPoJo.getCanBrandList(), null);
                        return getFinalResultReportId(reportId);
                    }
                }
                //省份权限不为空 品牌权限为空
                if (!provinceBrandPoJo.getOwnProvinceList().isEmpty() && provinceBrandPoJo.getOwnBrandList().isEmpty()) {
                    List<Long> ownProvinceReportId = getReportIdByProvince(provinceBrandPoJo.getOwnProvinceList(), null, null);
                    reportId = getReportIdByBrand(provinceBrandPoJo.getSearchBrandList(), ownProvinceReportId);
                    return getFinalResultReportId(reportId);
                }
            } else {
                //省份权限 品牌权限都不为空时
                List<Long> ownProvinceReportId = getReportIdByProvince(provinceBrandPoJo.getOwnProvinceList(), null, null);
                reportId = getReportIdByBrand(provinceBrandPoJo.getSearchBrandList(), ownProvinceReportId);
                return getFinalResultReportId(reportId);
            }
        }

        //筛选条件：省份+品牌
        if (StringUtils.isNotEmpty(province) && StringUtils.isNotEmpty(brand)) {
            //无匹省份权限+无品牌权限
            if (provinceBrandPoJo.getOwnProvinceList().isEmpty() && provinceBrandPoJo.getOwnBrandList().isEmpty()) {
                return new SearchVoId();
            }
            //经销商-->销售 身份权限为空 品牌权限不为空
            if (provinceBrandPoJo.getOwnProvinceList().isEmpty() && !provinceBrandPoJo.getOwnBrandList().isEmpty()) {
                if (provinceBrandPoJo.getCanBrandList().isEmpty()) {
                    return new SearchVoId();
                }
                List<Long> brandReportId = getReportIdByBrand(provinceBrandPoJo.getCanBrandList(), null);
                List<Long> provinceReportId = getReportIdByProvince(
                        null, provinceBrandPoJo.getSearchProvinceList(), brandReportId);
                return getFinalResultReportId(provinceReportId);
            }
            //经销商-->销售 身份权限不为空 品牌权限为空
            if (!provinceBrandPoJo.getOwnProvinceList().isEmpty() && provinceBrandPoJo.getOwnBrandList().isEmpty()) {
                if (provinceBrandPoJo.getCanProvinceList().isEmpty()) {
                    return new SearchVoId();
                }
                List<Long> provinceReportId = getReportIdByProvince(
                        provinceBrandPoJo.getCanProvinceList(), null, null);
                List<Long> reportIdByBrand = getReportIdByBrand(provinceBrandPoJo.getSearchBrandList(), provinceReportId);
                return getFinalResultReportId(reportIdByBrand);
            }
            //经销商-->销售 如果有匹配的省份  拉取能筛选的省份+搜索的品牌
            if (provinceBrandPoJo.getOwnBrandList().isEmpty() && !provinceBrandPoJo.getCanProvinceList().isEmpty()) {
                List<Long> provinceReportId = getReportIdByProvince(
                        provinceBrandPoJo.getCanProvinceList(), null, null);
                List<Long> reportIdByBrand = getReportIdByBrand(provinceBrandPoJo.getSearchBrandList(), provinceReportId);
                return getFinalResultReportId(reportIdByBrand);
            }
            List<Long> reportId;
            //权限有能筛选的省份和能筛选的该品牌 拉取能筛选的省份+能筛选的品牌
            if (!provinceBrandPoJo.getCanProvinceList().isEmpty() &&
                    !provinceBrandPoJo.getCanBrandList().isEmpty()) {
                //拉取能筛选省份的报告ID
                List<Long> provinceReportId = getReportIdByProvince(
                        provinceBrandPoJo.getCanProvinceList(), null, null);
                //拉取能筛选品牌的报告ID
                reportId = getReportIdByBrand(provinceBrandPoJo.getCanBrandList(), provinceReportId);
                return getFinalResultReportId(reportId);
            }
            //权限有能筛选的省份和不能筛选的该品牌 拉取能筛选的省份+筛选品牌
            if (!provinceBrandPoJo.getCanProvinceList().isEmpty() &&
                    provinceBrandPoJo.getCanBrandList().isEmpty()) {
                //拉取能筛选省份的报告ID
                List<Long> provinceReportId = getReportIdByProvince(
                        provinceBrandPoJo.getCanProvinceList(), null, null);
                //拉取筛选品牌
                reportId = getReportIdByBrand(provinceBrandPoJo.getSearchBrandList(), provinceReportId);
                return getFinalResultReportId(reportId);
            }
            //权限无该省份和有该品牌 拉取筛选省份+该品牌
            if (provinceBrandPoJo.getCanProvinceList().isEmpty() &&
                    !provinceBrandPoJo.getCanBrandList().isEmpty()) {
                //拉取该品牌
                List<Long> brandReportId = getReportIdByBrand(provinceBrandPoJo.getCanBrandList(), null);
                //拉取筛选省份
                reportId = getReportIdByProvince(
                        null, provinceBrandPoJo.getSearchProvinceList(), brandReportId);
                return getFinalResultReportId(reportId);
            }
            if (provinceBrandPoJo.getCanProvinceList().isEmpty() &&
                    provinceBrandPoJo.getCanBrandList().isEmpty()) {
                return new SearchVoId();
            }
        }
        //返回默认的数据
        //经销商-->销售 返回负责的品牌
        if (provinceBrandPoJo.getOwnProvinceList().isEmpty()) {
            List<Long> brandReportId = getReportIdByBrand(provinceBrandPoJo.getOwnBrandList(), null);
            return getFinalResultReportId(brandReportId);
        }
        List<Long> ownProvinceReportId = getReportIdByProvince(
                provinceBrandPoJo.getOwnProvinceList(), null, null);
        List<Long> brandReportId = getReportIdByBrand(provinceBrandPoJo.getOwnBrandList(), null);
        ownProvinceReportId.addAll(brandReportId);
        return getFinalResultReportId(ownProvinceReportId);
    }

    /**
     * 通过省份获取基础报告ID
     *
     * @param provinceStrList  有权限筛的选省份
     * @param provinceStrArray 筛选的省份
     * @return 基础报告ID
     */
    private List<Long> getReportIdByProvince(
            List<String> provinceStrList, String[] provinceStrArray, List<Long> brandReportId) {

        StationColorReportExample stationColorReportExample = new StationColorReportExample();
        Criteria criteria = stationColorReportExample.createCriteria();
        criteria.andDeletedEqualTo(false).andEnabledEqualTo(true).andQuestionIdEqualTo(173L);


        if (null != brandReportId && !brandReportId.isEmpty()) {
            StationReportExample stationReportExample = new StationReportExample();
            stationReportExample.createCriteria().andIdIn(brandReportId.stream().distinct().collect(
                Collectors.toList()));
            List<com.ugoodtech.mdcc.core.model.entity.StationReport> stationReportList = stationReportMapper.selectByExample(
                stationReportExample);
            if (CollectionUtils.isEmpty(stationReportList)) {
                return new ArrayList<>(0);
            }
            List<Long> stationReportIdList = stationReportList.stream()
                .map(com.ugoodtech.mdcc.core.model.entity.StationReport::getId)
                .collect(Collectors.toList());
            criteria.andReportIdIn(stationReportIdList);
        }
        if (null != provinceStrList && !provinceStrList.isEmpty()) {
            criteria.andAnswerOtherIdIn(provinceStrList);
        }
        if (null != provinceStrArray && provinceStrArray.length != 0) {
            criteria.andAnswerOtherIdIn(Arrays.asList(provinceStrArray));
        }
        // /**
        //  * 通过BooleanBuilder查出报告ID
        //  *
        //  * @param booleanBuilder BooleanBuilder
        //  * @return 报告ID
        //  */
        // private List<Long> getStationReportIdByBuilder(BooleanBuilder booleanBuilder) {
        //     List<Long> stationReportId = new ArrayList<>();
        //     List<StationColorReport> stationColorReportList =
        //             (List<StationColorReport>) stationColorReportRepository.findAll(booleanBuilder);
        //     for (StationColorReport stationColorReport : stationColorReportList) {
        //         stationReportId.add(stationColorReport.getStationReport().getId());
        //     }
        //     return stationReportId;
        // }

        List<com.ugoodtech.mdcc.core.model.entity.StationColorReport> stationColorReportList = stationColorReportMapper.selectByExample(
            stationColorReportExample);
        return stationColorReportList.stream().map(
            com.ugoodtech.mdcc.core.model.entity.StationColorReport::getReportId).collect(
            Collectors.toList());
    }

    /**
     * 通过品牌获取基础报告ID
     *
     * @param brandList 品牌集合
     * @return 基础报告ID
     */
    private List<Long> getReportIdByBrand(List<Long> brandList, List<Long> provinceReportId) {
        Map<Long, Integer> reportId = new HashMap<>();
//        if (CollectionUtils.isEmpty(brandList)){
//            List<StationColorReport> stationColorReportList =
//                (List<StationColorReport>) stationColorReportRepository.findAll();
//            for (StationColorReport stationColorReport : stationColorReportList) {
//                reportId.put(stationColorReport.getStationReport().getId(), 1);
//            }
//            return new ArrayList<>(reportId.keySet());
//        }
            QStationColorReport qStationColorReport = QStationColorReport.stationColorReport;
            BooleanBuilder builder = getQStationColorReport(qStationColorReport, 8L);
            if (null != provinceReportId && !provinceReportId.isEmpty()) {
                builder.and(qStationColorReport.stationReport.id.in(provinceReportId));
            }
            BooleanBuilder brandOr = new BooleanBuilder();
            for (Long brand : brandList) {
                brandOr.or(qStationColorReport.answerId.like("%" + brand + "%"));
            }
            builder.and(brandOr);
            List<StationColorReport> stationColorReportList =
                    (List<StationColorReport>) stationColorReportRepository.findAll(builder);
            for (StationColorReport stationColorReport : stationColorReportList) {
                reportId.put(stationColorReport.getStationReport().getId(), 1);
            }
        return new ArrayList<>(reportId.keySet());
    }

    /**
     * 根据不同的QuestionId获取BooleanBuilder对象
     *
     * @param qStationColorReport QStationColorReport
     * @param questionId          问题ID
     * @return BooleanBuilder
     */
    private BooleanBuilder getQStationColorReport(QStationColorReport qStationColorReport, Long questionId) {
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qStationColorReport.deleted.eq(false));
        builder.and(qStationColorReport.enabled.eq(true));
        builder.and(qStationColorReport.questionId.eq(questionId));
        return builder;
    }

    // /**
    //  * 通过BooleanBuilder查出报告ID
    //  *
    //  * @param booleanBuilder BooleanBuilder
    //  * @return 报告ID
    //  */
    // private List<Long> getStationReportIdByBuilder(BooleanBuilder booleanBuilder) {
    //     List<Long> stationReportId = new ArrayList<>();
    //     List<StationColorReport> stationColorReportList =
    //             (List<StationColorReport>) stationColorReportRepository.findAll(booleanBuilder);
    //     for (StationColorReport stationColorReport : stationColorReportList) {
    //         stationReportId.add(stationColorReport.getStationReport().getId());
    //     }
    //     return stationReportId;
    // }

    /**
     * 获取最终的报告ID
     *
     * @param stationReportId 过滤出来的报告ID
     * @return 最终的报告ID
     */
    private SearchVoId getFinalResultReportId(List<Long> stationReportId) {
        // QStationReport qStationReport = QStationReport.stationReport;
        // BooleanBuilder builder = new BooleanBuilder();
        // builder.and(qStationReport.deleted.eq(false));
        // builder.and(qStationReport.enabled.eq(true));
        // builder.and(qStationReport.category.eq(Constants.TECHCOLOR_REPORT));
        // builder.and(qStationReport.station.checkStation.eq(true));
        // builder.and(qStationReport.id.in(stationReportId));
        // List<StationReport> stationReportList =
        //         (List<StationReport>) stationReportRepository.findAll(builder);
        // List<Long> resultStationReportId = new ArrayList<>();
        // List<Long> resultStationId = new ArrayList<>();
        // for (StationReport stationReport : stationReportList) {
        //     resultStationReportId.add(stationReport.getId());
        //     resultStationId.add(stationReport.getStation().getId());
        // }
        // SearchVoId searchVoId = new SearchVoId();
        // searchVoId.setResultStationReportId(resultStationReportId);
        // searchVoId.setResultStationId(resultStationId);
        // return searchVoId;

        StationsExample stationsExample = new StationsExample();
        stationsExample.createCriteria().andCheckStationEqualTo(true);

        List<Stations> stations = stationsMapper.selectByExample(stationsExample);
        if (CollectionUtils.isEmpty(stations)) {
            SearchVoId searchVoId = new SearchVoId();
            searchVoId.setResultStationReportId(new ArrayList<>(0));
            searchVoId.setResultStationId(new ArrayList<>(0));
            return searchVoId;
        }
        StationReportExample stationReportExample = new StationReportExample();
        StationReportExample.Criteria criteria = stationReportExample.createCriteria();
        criteria.andDeletedEqualTo(false)
            .andEnabledEqualTo(true)
            .andCategoryEqualTo(Constants.TECHCOLOR_REPORT)
            .andStationIdIn(stations.stream().map(Stations::getId).distinct().collect(Collectors.toList()))
            .andIdIn(stationReportId.stream().distinct().collect(Collectors.toList()));

        List<com.ugoodtech.mdcc.core.model.entity.StationReport> stationReportList = stationReportMapper.selectByExample(
            stationReportExample);
        List<Long> resultStationReportId = new ArrayList<>();
        List<Long> resultStationId = new ArrayList<>();
        for (com.ugoodtech.mdcc.core.model.entity.StationReport stationReport : stationReportList) {
            resultStationReportId.add(stationReport.getId());
            resultStationId.add(stationReport.getStationId());
        }
        SearchVoId searchVoId = new SearchVoId();
        searchVoId.setResultStationReportId(resultStationReportId);
        searchVoId.setResultStationId(resultStationId);
        return searchVoId;


    }

}
